/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights
 * reserved. <a>http://www.cqcis.com</a>
 */
package com.cqcis.uip.base.framework.utils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 注解工具类
 * 
 * @author huangmy
 * @date   2008-6-24
 */
public class AnnotationUtil {
	/**
	 * 查找在类上的annotation
	 * 
	 * @param clazz
	 * @param annotationClazz
	 * @return
	 */
	public static Annotation getAnnotationForClass(Class<?> clazz, Class<? extends Annotation> annotationClazz) {
		Annotation role = clazz.getAnnotation(annotationClazz);
		if (role != null) {
			return role;
		}
				
		return null;
	}
	
	/**
	 * 获取方法上的注解
	 * 
	 * @param method
	 * @param annotationClazz
	 * @return
	 */
	public static Annotation getAnnotationForMethod(Method method, Class<? extends Annotation> annotationClazz) {
		Annotation role = method.getAnnotation(annotationClazz);
		if (role != null) {
			return role;
		}
				
		return null;
	}
	
	/**
	 * 查找在类上的annotation, 如果类上表示了忽略注解，则返回null
	 * 
	 * @param clazz
	 * @param annotationClazz
	 * @param annotationIgnoreClazz 如果不为null， 则为忽略的注解
	 * @return
	 */
	public static Annotation findAnnotationForClass(Class<?> clazz, Class<? extends Annotation> annotationClazz, Class<? extends Annotation> annotationIgnoreClazz) {
		Annotation roleIgnore = clazz.getAnnotation(annotationIgnoreClazz);
		if (roleIgnore != null) {
			return null;
		}
		
		Annotation role = clazz.getAnnotation(annotationClazz);
		if (role != null) {
			return role;
		}
		
		Class<?>[] interfaces = clazz.getInterfaces();
		if (interfaces != null) {			
			for (Class<?> f : interfaces) {				
				role = f.getAnnotation(annotationClazz);
				if (role != null) {	
					return role;
				}
			}
		}
		
		return null;
	}
	
	/**
	 * 获取类上的服务角色注解，如果没有，继续查找实现的接口、继承的父类
	 * 
	 * @param clazz
	 * @param annotationClazz
	 * @param annotationIgnoreClazz 如果不为null， 则为忽略的注解
	 * @return
	 */
	public static Annotation findDeepAnnotationForClass(Class<?> clazz, Class<? extends Annotation> annotationClazz, Class<? extends Annotation> annotationIgnoreClazz) {
		Annotation roleIgnore = clazz.getAnnotation(annotationIgnoreClazz);
		if (roleIgnore != null) {
			return null;
		}
		
		Annotation role = findAnnotationForClass(clazz, annotationClazz, annotationIgnoreClazz);
		if (role != null) {
			return role;
		}
		
		// 继续找父类的
		Class<?> parentClazz = null;
		while ((parentClazz = clazz.getSuperclass()) != null) {
			clazz = parentClazz;
			role = findAnnotationForClass(parentClazz, annotationClazz, annotationIgnoreClazz);
			if (role != null) {
				return role;
			}
		}
		
		return null;
	}
	
	/**
	 * 查找指定class上标注有指定注解的interface
	 * 
	 * @param clazz
	 * @param annotationClazz
	 * @return
	 */
	public static Class<?> findDeepAnnotationInterfaceForClass(Class<?> clazz, Class<? extends Annotation> annotationClazz) {
		Class<?>[] interfaces = clazz.getInterfaces();
		if (interfaces != null) {			
			for (Class<?> f : interfaces) {				
				Annotation role = f.getAnnotation(annotationClazz);
				if (role != null) {	
					return f;
				}
			}
		}
		
		return null;
	}
	
	/**
	 * 查找在类上的带annotation的方法列表
	 * 
	 * @param clazz
	 * @param annotationClazz
	 * @return
	 */
	public static Method[] findAnnotationMethodsFor(Class<?> clazz, Class<? extends Annotation> annotationClazz) {
		List<Method> methods = new ArrayList<Method>();
		Method[] ms = clazz.getMethods();
		if (ms != null) {
			for (Method m : ms) {
				Annotation role = m.getAnnotation(annotationClazz);
				if (role != null) {
					methods.add(m);
				}
			}
		}
		
		return methods.toArray(new Method[methods.size()]);
	}
}
